<html>
<head><meta charset="utf-8"><title>cost of supporting longjmp without annotations · project-ffi-unwind · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/index.html">project-ffi-unwind</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations.html">cost of supporting longjmp without annotations</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="226054427"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/cost%20of%20supporting%20longjmp%20without%20annotations/near/226054427" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> BatmanAoD (Kyle Strand) <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations.html#226054427">(Feb 11 2021 at 20:41)</a>:</h4>
<p><span class="user-mention silent" data-user-id="120791">RalfJ</span> <a href="#narrow/stream/210922-project-ffi-unwind/topic/UB.20to.20skip.20destructors/near/201472007">said</a>:</p>
<blockquote>
<p>I guess there is a discussion to be had if this is an optimization that we want. I am really proud that Stacked Borrows can provide it, but there's clearly a trade-off. OTOH, this is an optimization that can benefit all code vs a rather niche feature. Still, worth a discussion it seems.</p>
</blockquote>
<p>I believe we're ready to have that discussion now. We published a <a href="https://blog.rust-lang.org/inside-rust/2021/01/26/ffi-unwind-longjmp.html">blog post</a> outlining how the annotation-based support for <code>longjmp</code> would work, but did not receive any responses to it over the course of two weeks. So, in the weekly meeting topic, we're wondering whether this optimization is actually worth adding the extra complexity of an annotation.</p>
<p><span class="user-mention" data-user-id="133247">@bjorn3</span> may also want to contribute to the discussion.</p>



<a name="226063073"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/cost%20of%20supporting%20longjmp%20without%20annotations/near/226063073" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oliver <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations.html#226063073">(Feb 11 2021 at 21:50)</a>:</h4>
<p>Everything I know about <code>longjmp</code> I learned in this blog: <a href="https://developer.r-project.org/Blog/public/2019/03/28/use-of-c-in-packages/index.html">https://developer.r-project.org/Blog/public/2019/03/28/use-of-c-in-packages/index.html</a></p>



<a name="227581653"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/cost%20of%20supporting%20longjmp%20without%20annotations/near/227581653" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations.html#227581653">(Feb 24 2021 at 11:05)</a>:</h4>
<p>So <span class="user-mention" data-user-id="143274">@Amanieu</span> <a href="#narrow/stream/210922-project-ffi-unwind/topic/weekly.20meeting/near/226051690">wrote</a> that the "only cost" with longjmp is not being able to move things to after calls -- that seems correct to me, except that I think this is kind of a big deal. We've been working hard to <em>enable</em> those sort of transformations. Now, you could argue that this is unnecessary, especially given that <code>panic!</code> is something we have to contend with!</p>



<a name="227581739"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/cost%20of%20supporting%20longjmp%20without%20annotations/near/227581739" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations.html#227581739">(Feb 24 2021 at 11:05)</a>:</h4>
<p>How can we make this discussion more evidence-based and less assertion-based? :)</p>



<a name="227581757"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/cost%20of%20supporting%20longjmp%20without%20annotations/near/227581757" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations.html#227581757">(Feb 24 2021 at 11:05)</a>:</h4>
<p>(cc <span class="user-mention" data-user-id="120791">@RalfJ</span>)</p>



<a name="227598035"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/cost%20of%20supporting%20longjmp%20without%20annotations/near/227598035" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations.html#227598035">(Feb 24 2021 at 13:33)</a>:</h4>
<p>With my "works around backend" hat on, I would quite hate having to keep possibility of longjmp in my head rather than expressed explicitly in code.</p>



<a name="227616973"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/cost%20of%20supporting%20longjmp%20without%20annotations/near/227616973" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations.html#227616973">(Feb 24 2021 at 15:37)</a>:</h4>
<p>I'm not sure that's quite true, unless you consider observable behaviour (IE. volatile access, I/O).<br>
The C standard specifies that after a longjmp, any non-volatile object (might also be constrained to automatic storage duration) modified since the corresponding setjmp has an indeterminate value, which translates to uninit in rust. So if you have</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">5</span><span class="p">;</span><span class="w"></span>
<span class="k">if</span><span class="w"> </span><span class="k">unsafe</span><span class="p">{</span><span class="n">setjmp</span><span class="p">(</span><span class="n">buf</span><span class="p">)}</span><span class="w"> </span><span class="o">==</span><span class="mi">0</span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">6</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="k">unsafe</span><span class="p">{</span><span class="n">longjmp</span><span class="p">(</span><span class="n">buf</span><span class="p">,</span><span class="mi">1</span><span class="p">))}</span><span class="w"></span>
<span class="p">}</span><span class="k">else</span><span class="p">{</span><span class="o">..</span><span class="p">.}</span><span class="w"></span>
</code></pre></div>
<p>then in the else branch, x is uninit, so the assignment can be moved, or even removed. </p>
<p>Of course, this presents a slightly different problem (in that x is now uninit, which is currently UB). Though if indeterminate is taken here as unspecified, it would be fine (but llvm may or may not be ok with that interpretation).</p>



<a name="227626714"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/cost%20of%20supporting%20longjmp%20without%20annotations/near/227626714" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations.html#227626714">(Feb 24 2021 at 16:24)</a>:</h4>
<p><span class="user-mention silent" data-user-id="123586">nagisa</span> <a href="#narrow/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations/near/227598035">said</a>:</p>
<blockquote>
<p>With my "works around backend" hat on, I would quite hate having to keep possibility of longjmp in my head rather than expressed explicitly in code.</p>
</blockquote>
<p>yes</p>



<a name="227626866"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/cost%20of%20supporting%20longjmp%20without%20annotations/near/227626866" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations.html#227626866">(Feb 24 2021 at 16:25)</a>:</h4>
<p><span class="user-mention" data-user-id="257758">@Connor Horman</span> that's interesting; there are I suppose other potential ways to go about specifying that we could do code motion</p>



<a name="227626908"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/cost%20of%20supporting%20longjmp%20without%20annotations/near/227626908" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations.html#227626908">(Feb 24 2021 at 16:25)</a>:</h4>
<p>it would require, I think, sacrificing some of the "ease of use" that stacked borrows is shooting for</p>



<a name="227628098"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/cost%20of%20supporting%20longjmp%20without%20annotations/near/227628098" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> BatmanAoD (Kyle Strand) <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations.html#227628098">(Feb 24 2021 at 16:31)</a>:</h4>
<p><span class="user-mention silent" data-user-id="123586">nagisa</span> <a href="#narrow/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations/near/227598035">said</a>:</p>
<blockquote>
<p>With my "works around backend" hat on, I would quite hate having to keep possibility of longjmp in my head rather than expressed explicitly in code.</p>
</blockquote>
<p>I agree with this (which is why I called the C status quo of "<code>longjmp</code> can happen anywhere, any time" a "wart"), but my concern is that it will be one more pain point in the "playing nice with existing systems software" domain.</p>



<a name="227628936"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/cost%20of%20supporting%20longjmp%20without%20annotations/near/227628936" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> BatmanAoD (Kyle Strand) <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations.html#227628936">(Feb 24 2021 at 16:36)</a>:</h4>
<p>(To be clear: this is a fear, not an appraisal. I agree with <span class="user-mention" data-user-id="116009">@nikomatsakis</span> that we need to find a way to make this discussion more evidence-based, and I would love to see evidence that my fear is misplaced, but I don't yet see a path toward gaining that confidence.)</p>



<a name="227637725"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/cost%20of%20supporting%20longjmp%20without%20annotations/near/227637725" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations.html#227637725">(Feb 24 2021 at 17:24)</a>:</h4>
<p>I suspect that actual usage of longjmp will be sufficiently rare that it seems perfectly reasonable to require either annotation or a compiler flag.</p>



<a name="227637758"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/cost%20of%20supporting%20longjmp%20without%20annotations/near/227637758" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations.html#227637758">(Feb 24 2021 at 17:24)</a>:</h4>
<p>The programs that need it really need it.</p>



<a name="227637818"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/cost%20of%20supporting%20longjmp%20without%20annotations/near/227637818" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations.html#227637818">(Feb 24 2021 at 17:25)</a>:</h4>
<p>But at the same time, the fraction of programs, even systems programs, using it is quite small.</p>



<a name="227660225"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/cost%20of%20supporting%20longjmp%20without%20annotations/near/227660225" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations.html#227660225">(Feb 24 2021 at 19:48)</a>:</h4>
<p>An alternative definition is that the contents of a <code>&amp;mut</code> are undefined after a <code>longjmp</code>: after all the <code>&amp;mut</code> promised exclusive access for the duration of the function but the <code>longjmp</code> violated that expectation by returning control early.</p>



<a name="227667024"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/cost%20of%20supporting%20longjmp%20without%20annotations/near/227667024" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations.html#227667024">(Feb 24 2021 at 20:32)</a>:</h4>
<p>I feel like I don't want the contents to be undefined</p>



<a name="227667048"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/cost%20of%20supporting%20longjmp%20without%20annotations/near/227667048" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations.html#227667048">(Feb 24 2021 at 20:32)</a>:</h4>
<p>people will wind up relying on them</p>



<a name="227667059"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/cost%20of%20supporting%20longjmp%20without%20annotations/near/227667059" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations.html#227667059">(Feb 24 2021 at 20:32)</a>:</h4>
<p>I want them to be defined to be what they should be</p>



<a name="227667080"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/cost%20of%20supporting%20longjmp%20without%20annotations/near/227667080" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations.html#227667080">(Feb 24 2021 at 20:32)</a>:</h4>
<p>and I just want the compiler to know when a longjmp happens</p>



<a name="227667089"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/cost%20of%20supporting%20longjmp%20without%20annotations/near/227667089" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations.html#227667089">(Feb 24 2021 at 20:32)</a>:</h4>
<p>since, as you said, it's unusual</p>



<a name="227667131"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/cost%20of%20supporting%20longjmp%20without%20annotations/near/227667131" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations.html#227667131">(Feb 24 2021 at 20:32)</a>:</h4>
<p>maybe the question: what is the case <em>against</em> an annotation?</p>



<a name="227667157"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/cost%20of%20supporting%20longjmp%20without%20annotations/near/227667157" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations.html#227667157">(Feb 24 2021 at 20:33)</a>:</h4>
<p>we should probably make a little doc to collect these things</p>



<a name="227676946"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/cost%20of%20supporting%20longjmp%20without%20annotations/near/227676946" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> BatmanAoD (Kyle Strand) <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations.html#227676946">(Feb 24 2021 at 21:34)</a>:</h4>
<p>The case against, I think, is that there is absolutely nothing the compiler can do to detect when <code>longjmp</code> actually happens, without like... reading C code, or guessing based on function signatures. So if an annotation is required for correctness, then there is ample opportunity for UB with un-annotated functions.</p>



<a name="227698545"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/cost%20of%20supporting%20longjmp%20without%20annotations/near/227698545" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations.html#227698545">(Feb 25 2021 at 00:18)</a>:</h4>
<p>Keep in mind that <code>pthread_exit</code> on non-glibc will directly exit the thread, which is equivalent to longjmp. So we would need this annotation for every FFI call which can potentially cause a thread exit. This includes all libc functions which are cancellable.</p>



<a name="227699724"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/cost%20of%20supporting%20longjmp%20without%20annotations/near/227699724" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> BatmanAoD (Kyle Strand) <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations.html#227699724">(Feb 25 2021 at 00:30)</a>:</h4>
<p>I think that's okay, as long as libc functions are typically called via the <code>libc</code> crate and that crate updates to use the annotations.</p>



<a name="227699956"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/cost%20of%20supporting%20longjmp%20without%20annotations/near/227699956" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> BatmanAoD (Kyle Strand) <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations.html#227699956">(Feb 25 2021 at 00:33)</a>:</h4>
<p>I also tend to think that it may be worthwhile to make any optimizations that would invalidate un-annotated code using <code>longjmp</code> opt-in, at least up until an edition boundary.</p>



<a name="227700071"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/cost%20of%20supporting%20longjmp%20without%20annotations/near/227700071" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> BatmanAoD (Kyle Strand) <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations.html#227700071">(Feb 25 2021 at 00:34)</a>:</h4>
<p>I.e. I think we would ideally support the annotation itself in all editions, but 2015 and 2018 would have a guarantee that <code>longjmp</code> across POFs wouldn't be UB. (Or maaaaaaybe there could be a compiler flag for it, though that's probably more trouble than it's worth.)</p>



<a name="227796778"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/cost%20of%20supporting%20longjmp%20without%20annotations/near/227796778" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations.html#227796778">(Feb 25 2021 at 16:37)</a>:</h4>
<p>That sounds reasonable.</p>



<a name="227817887"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/cost%20of%20supporting%20longjmp%20without%20annotations/near/227817887" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations.html#227817887">(Feb 25 2021 at 18:56)</a>:</h4>
<p><span class="user-mention silent" data-user-id="120076">BatmanAoD (Kyle Strand)</span> <a href="#narrow/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations/near/227699956">said</a>:</p>
<blockquote>
<p>I also tend to think that it may be worthwhile to make any optimizations that would invalidate un-annotated code using <code>longjmp</code> opt-in, at least up until an edition boundary.</p>
</blockquote>
<p>does LLVM perform any such optimizations? If yes, it might be had to make this opt-in.</p>



<a name="227818126"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/cost%20of%20supporting%20longjmp%20without%20annotations/near/227818126" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> BatmanAoD (Kyle Strand) <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations.html#227818126">(Feb 25 2021 at 18:58)</a>:</h4>
<p>I can't imagine it would, since in C++ it's always legal to <code>longjmp</code> over POFs.</p>



<a name="227818178"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/cost%20of%20supporting%20longjmp%20without%20annotations/near/227818178" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations.html#227818178">(Feb 25 2021 at 18:58)</a>:</h4>
<p>and C++ doesn't have C-style rules like "all these values become indeterminate"? Because if it does, then LLVM would well be in its right to "invalidate" such code, at least in the sense that the values it works on become all messed up. I'd be rather surprised if LLVM doesn't do such optimizations.</p>



<a name="227818310"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/cost%20of%20supporting%20longjmp%20without%20annotations/near/227818310" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations.html#227818310">(Feb 25 2021 at 18:59)</a>:</h4>
<p>I agree with <span class="user-mention" data-user-id="116009">@nikomatsakis</span> that rules like "all values X become indeterminate/uninit/... on longjmp" are massive footguns. It is really hard to program correctly against those rules, and really easy to miss some variable and accidentally rely on its value. I could imagine implementing something like this in Miri (so making this rule operational is not the main issue), but still it'd be hard to make sure one gets this right (such low-level code often cannot run in Miri since it interacts with things Miri cannot emulate).</p>



<a name="227818507"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/cost%20of%20supporting%20longjmp%20without%20annotations/near/227818507" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> BatmanAoD (Kyle Strand) <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations.html#227818507">(Feb 25 2021 at 19:00)</a>:</h4>
<p>To be honest I don't quite understand the C rule, but I would expect that C++ has at least as much UB as C concerning <code>longjmp</code>.</p>



<a name="227818554"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/cost%20of%20supporting%20longjmp%20without%20annotations/near/227818554" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> BatmanAoD (Kyle Strand) <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations.html#227818554">(Feb 25 2021 at 19:00)</a>:</h4>
<p>So let me backtrack on that "can't image" phrasing a bit <span aria-label="laughing" class="emoji emoji-1f606" role="img" title="laughing">:laughing:</span></p>



<a name="227818759"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/cost%20of%20supporting%20longjmp%20without%20annotations/near/227818759" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations.html#227818759">(Feb 25 2021 at 19:01)</a>:</h4>
<p>also FWIW, edition-specific optimization flags are... tricky, since optimizations work on MIR/LLVM IR where code from many editions can be mixed (e.g. after inlining)</p>



<a name="227819275"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/cost%20of%20supporting%20longjmp%20without%20annotations/near/227819275" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> BatmanAoD (Kyle Strand) <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations.html#227819275">(Feb 25 2021 at 19:05)</a>:</h4>
<p>I was imagining that prohibiting such optimizations would be equivalent to marking all functions with the "cancelable" annotation. I.e., prior to the 2021 edition, the "cancelable" annotation would only be useful for diagnostics and wouldn't impact codegen.</p>



<a name="227820783"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/cost%20of%20supporting%20longjmp%20without%20annotations/near/227820783" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> BatmanAoD (Kyle Strand) <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations.html#227820783">(Feb 25 2021 at 19:14)</a>:</h4>
<p>ISO C11:</p>
<blockquote>
<p>except  that  the  values  ofobjects  of  automatic  storage  duration  that  are  local  to  the  function  containing  theinvocation  of  the  correspondingsetjmpmacro  that  do  not  have  volatile-qualified  typeand  have  been  changed  between  thesetjmpinvocation  andlongjmpcall  areindeterminate.</p>
</blockquote>



<a name="227820820"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/cost%20of%20supporting%20longjmp%20without%20annotations/near/227820820" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> BatmanAoD (Kyle Strand) <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations.html#227820820">(Feb 25 2021 at 19:14)</a>:</h4>
<p>(7.13.2.3)</p>



<a name="227820857"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/cost%20of%20supporting%20longjmp%20without%20annotations/near/227820857" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> BatmanAoD (Kyle Strand) <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations.html#227820857">(Feb 25 2021 at 19:15)</a>:</h4>
<p>oh jeeze, sorry about the formatting there</p>



<a name="227822067"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/cost%20of%20supporting%20longjmp%20without%20annotations/near/227822067" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> BatmanAoD (Kyle Strand) <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations.html#227822067">(Feb 25 2021 at 19:22)</a>:</h4>
<p>Since <code>setjmp</code> can't be used via something like <code>return setjmp(env)</code>, a Rust invocation of <code>setjmp</code> would, I think, need to pass a callback in order to invoke further Rust code prior to <code>longjmp</code>. So I think the only place where variables are left in an indeterminate state is in the C code itself...?</p>



<a name="227822136"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/cost%20of%20supporting%20longjmp%20without%20annotations/near/227822136" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> BatmanAoD (Kyle Strand) <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations.html#227822136">(Feb 25 2021 at 19:23)</a>:</h4>
<p>Which would of course be a problem for Rust if the C code passes those variables to the Rust callback, so that should probably be illegal</p>



<a name="227822218"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/cost%20of%20supporting%20longjmp%20without%20annotations/near/227822218" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> BatmanAoD (Kyle Strand) <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations.html#227822218">(Feb 25 2021 at 19:23)</a>:</h4>
<p>But I think any variables defined by Rust would not be invalidated by the C runtime behavior. At least, I don't see any reason in the C standard for that to happen.</p>



<a name="227822624"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/cost%20of%20supporting%20longjmp%20without%20annotations/near/227822624" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> BatmanAoD (Kyle Strand) <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations.html#227822624">(Feb 25 2021 at 19:25)</a>:</h4>
<p><span class="user-mention silent" data-user-id="120076">BatmanAoD (Kyle Strand)</span> <a href="#narrow/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations/near/227822067">said</a>:</p>
<blockquote>
<p>Since <code>setjmp</code> can't be used via something like <code>return setjmp(env)</code>, a Rust invocation of <code>setjmp</code> would, I think, need to pass a callback in order to invoke further Rust code prior to <code>longjmp</code>. So I think the only place where variables are left in an indeterminate state is in the C code itself...?</p>
</blockquote>
<p>...or the C itself could invoke Rust. That case also seems relatively tame, though.</p>



<a name="227842969"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/cost%20of%20supporting%20longjmp%20without%20annotations/near/227842969" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations.html#227842969">(Feb 25 2021 at 21:35)</a>:</h4>
<blockquote>
<p>and C++ doesn't have C-style rules like "all these values become indeterminate"? Because if it does, then LLVM would well be in its right to "invalidate" such code, at least in the sense that the values it works on become all messed up. I'd be rather surprised if LLVM doesn't do such optimizations.</p>
</blockquote>
<p>According to <a href="https://eel.is/c++draft/csetjmp.syn">https://eel.is/c++draft/csetjmp.syn</a>, it's just C's setjmp.h, but it further restricts longjmp to those that cross "pof"s.</p>
<blockquote>
<p>Since <code>setjmp</code> can't be used via something like <code>return setjmp(env)</code>, a Rust invocation of <code>setjmp</code> would, I think, need to pass a callback in order to invoke further Rust code prior to <code>longjmp</code>. So I think the only place where variables are left in an indeterminate state is in the C code itself...?</p>
</blockquote>
<p>Ah yeah, that's true (unless you grab a compiler builtin version from somewhere, and call it).</p>



<a name="227847362"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/cost%20of%20supporting%20longjmp%20without%20annotations/near/227847362" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> BatmanAoD (Kyle Strand) <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations.html#227847362">(Feb 25 2021 at 22:06)</a>:</h4>
<p>In C99 and onward, C has essentially the same limitation, because apparently variable-length arrays are heap-allocated and therefore freed by something akin to a destructor. (TIL; I thought C somehow cleverly supported variable-size stack elements.)</p>



<a name="227849729"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/cost%20of%20supporting%20longjmp%20without%20annotations/near/227849729" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations.html#227849729">(Feb 25 2021 at 22:23)</a>:</h4>
<p>Actually, that's not quite true.<br>
Jumping into the scope of a VLA after leaving it is UB, but crossing the scopes of other VLAs is not (it's just unspecified whether those get deallocated when you do so). (Also, VLAs can be stack allocated, and they can be heap allocated)</p>



<a name="227851001"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/cost%20of%20supporting%20longjmp%20without%20annotations/near/227851001" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> BatmanAoD (Kyle Strand) <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations.html#227851001">(Feb 25 2021 at 22:33)</a>:</h4>
<p>Ah. Okay, interesting.</p>



<a name="227860860"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/cost%20of%20supporting%20longjmp%20without%20annotations/near/227860860" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations.html#227860860">(Feb 26 2021 at 00:04)</a>:</h4>
<p>You can also register cleanups in GCC with <code>__cleanup__</code> which probably doesn't interact at all well with setjmp/longjmp</p>



<a name="227956637"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/cost%20of%20supporting%20longjmp%20without%20annotations/near/227956637" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations.html#227956637">(Feb 26 2021 at 16:56)</a>:</h4>
<p><code>__cleanup__</code> is basically a C++ destructor. It is ignored by <code>longjmp</code>.</p>



<a name="227956947"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/cost%20of%20supporting%20longjmp%20without%20annotations/near/227956947" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations.html#227956947">(Feb 26 2021 at 16:58)</a>:</h4>
<p>The <code>setjmp</code> API is a horribly hack that only exists because C doesn't have closures. A safe Rust API for it would be <code>fn setjmp(f: impl FnOnce(JmpBuf&lt;'_, E&gt;) -&gt; T) -&gt; Result&lt;T, E&gt;</code>.</p>



<a name="227957258"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/cost%20of%20supporting%20longjmp%20without%20annotations/near/227957258" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations.html#227957258">(Feb 26 2021 at 17:00)</a>:</h4>
<p>However this is not the issue here (we're never going to support the <code>setjmp</code> hackery in Rust anyways). The issue is essentially: <code>longjmp</code> skips destructors, so it is equivalent to an unwind if there are no destructors. Is the Rust compiler allowed to insert destructors out of thin air (e.g. by sinking code past a function call into both the unwind and normal paths).</p>



<a name="227963461"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/cost%20of%20supporting%20longjmp%20without%20annotations/near/227963461" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> BatmanAoD (Kyle Strand) <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations.html#227963461">(Feb 26 2021 at 17:43)</a>:</h4>
<p><span class="user-mention silent" data-user-id="143274">Amanieu</span> <a href="#narrow/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations/near/227957258">said</a>:</p>
<blockquote>
<p>However this is not the issue here (we're never going to support the <code>setjmp</code> hackery in Rust anyways). The issue is essentially: <code>longjmp</code> skips destructors, so it is equivalent to an unwind if there are no destructors. Is the Rust compiler allowed to insert destructors out of thin air (e.g. by sinking code past a function call into both the unwind and normal paths).</p>
</blockquote>
<p>This is equivalent to "can the compiler turn POFs into non-POFs", right? Or am I misunderstanding?</p>



<a name="227969700"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/cost%20of%20supporting%20longjmp%20without%20annotations/near/227969700" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations.html#227969700">(Feb 26 2021 at 18:23)</a>:</h4>
<p>Yes, essentially</p>



<a name="227970238"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/cost%20of%20supporting%20longjmp%20without%20annotations/near/227970238" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> BatmanAoD (Kyle Strand) <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations.html#227970238">(Feb 26 2021 at 18:27)</a>:</h4>
<p>So, I think the answer I lean toward is: in 2015 and 2018, no. In 2021 and onward, yes, unless a function is annotated "cancelable".</p>



<a name="227970553"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/cost%20of%20supporting%20longjmp%20without%20annotations/near/227970553" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> BatmanAoD (Kyle Strand) <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations.html#227970553">(Feb 26 2021 at 18:29)</a>:</h4>
<p>(and in 2015 and 2018, if the compiler can prove that the function can't be present in a stack where arbitrary C code might be invoked before the function returns, it can go ahead and insert such destructors anyway)</p>



<a name="228045984"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/cost%20of%20supporting%20longjmp%20without%20annotations/near/228045984" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations.html#228045984">(Feb 27 2021 at 09:21)</a>:</h4>
<p><span class="user-mention silent" data-user-id="143274">Amanieu</span> <a href="#narrow/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations/near/227957258">said</a>:</p>
<blockquote>
<p>However this is not the issue here (we're never going to support the <code>setjmp</code> hackery in Rust anyways). The issue is essentially: <code>longjmp</code> skips destructors, so it is equivalent to an unwind if there are no destructors. Is the Rust compiler allowed to insert destructors out of thin air (e.g. by sinking code past a function call into both the unwind and normal paths).</p>
</blockquote>
<p>it's not just this</p>



<a name="228046022"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/cost%20of%20supporting%20longjmp%20without%20annotations/near/228046022" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations.html#228046022">(Feb 27 2021 at 09:22)</a>:</h4>
<p>because if you have <code>-Cpanic=abort</code>, then it's not about inserting destructors</p>



<a name="228046038"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/cost%20of%20supporting%20longjmp%20without%20annotations/near/228046038" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations.html#228046038">(Feb 27 2021 at 09:22)</a>:</h4>
<p><span class="user-mention silent" data-user-id="120791">RalfJ</span> <a href="#narrow/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations/near/227818759">said</a>:</p>
<blockquote>
<p>also FWIW, edition-specific optimization flags are... tricky, since optimizations work on MIR/LLVM IR where code from many editions can be mixed (e.g. after inlining)</p>
</blockquote>
<p>This doesn't seem right, because of what <span class="user-mention" data-user-id="120076">@BatmanAoD (Kyle Strand)</span> said -- in the MIR, functions require an annotation, but the compiler inserts it on your behalf during MIR lowering.</p>



<a name="228046126"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/cost%20of%20supporting%20longjmp%20without%20annotations/near/228046126" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations.html#228046126">(Feb 27 2021 at 09:24)</a>:</h4>
<p><span class="user-mention silent" data-user-id="143274">Amanieu</span> <a href="#narrow/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations/near/227698545">said</a>:</p>
<blockquote>
<p>Keep in mind that <code>pthread_exit</code> on non-glibc will directly exit the thread, which is equivalent to longjmp. So we would need this annotation for every FFI call which can potentially cause a thread exit. This includes all libc functions which are cancellable.</p>
</blockquote>
<p>It feels to me like putting burdens on folks who use <code>pthread_exit</code> is ok. You already have to be very careful on how you use this. I guess, like <span class="user-mention" data-user-id="120076">@BatmanAoD (Kyle Strand)</span> said, that this can be handled by a central abstraction as well.</p>



<a name="228046133"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/cost%20of%20supporting%20longjmp%20without%20annotations/near/228046133" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations.html#228046133">(Feb 27 2021 at 09:24)</a>:</h4>
<p>I'm feeling like this discussion has gone long enough that it'd be useful to have a write-up.</p>



<a name="228054743"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/cost%20of%20supporting%20longjmp%20without%20annotations/near/228054743" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations.html#228054743">(Feb 27 2021 at 12:15)</a>:</h4>
<p><span class="user-mention silent" data-user-id="120076">BatmanAoD (Kyle Strand)</span> <a href="#narrow/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations/near/227822067">said</a>:</p>
<blockquote>
<p>Since <code>setjmp</code> can't be used via something like <code>return setjmp(env)</code>, a Rust invocation of <code>setjmp</code> would, I think, need to pass a callback in order to invoke further Rust code prior to <code>longjmp</code>. So I think the only place where variables are left in an indeterminate state is in the C code itself...?</p>
</blockquote>
<p>So setjmp is only "toxic" to local variables in the function that invokes it, but not in other functions? that makes no sense at all to me, why would outlining make any difference here?</p>



<a name="228060627"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/cost%20of%20supporting%20longjmp%20without%20annotations/near/228060627" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> BatmanAoD (Kyle Strand) <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations.html#228060627">(Feb 27 2021 at 14:09)</a>:</h4>
<p>Hm, maybe because they may or may not be captured and restored restored by the jumpbuf? I don't know. I agree it doesn't seem to make much sense.</p>



<a name="228060823"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/210922-project-ffi-unwind/topic/cost%20of%20supporting%20longjmp%20without%20annotations/near/228060823" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> BatmanAoD (Kyle Strand) <a href="https://rust-lang.github.io/zulip_archive/stream/210922-project-ffi-unwind/topic/cost.20of.20supporting.20longjmp.20without.20annotations.html#228060823">(Feb 27 2021 at 14:12)</a>:</h4>
<p>That's all that the standard calls out in that section, at least.</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>